package com.datatools.ui.sqledit;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.*;
import javax.swing.text.rtf.RTFEditorKit;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.Serializable;
import java.util.StringTokenizer;

/**
 * SQL 编辑器
 */
public class SQLEdit extends JTextPane implements Serializable {
    private static final long serialVersionUID = 1L;
    //样式池及其关联的资源
    private StyleContext styleContext;
    //可以用类似于RTF格式的字符和段落样式标记的文档。本文档的元素结构表示样式运行的样式交叉。这些样式运行被映射到段落元素结构（可以驻留在其他结构中）。由于将逻辑样式分配给段落边界，因此样式在段落边界处中断。
    //警告： 此类的序列化对象将与以后的Swing版本不兼容。当前的序列化支持适用于运行相同版本的Swing的应用程序之间的短期存储或RMI。从1.4版本开始，该java.beans软件包中已添加了对所有JavaBeans™的长期存储的支持。请看XMLEncoder。
    private DefaultStyledDocument defaultStyledDocument;
    //关键字属性接口
    private MutableAttributeSet keyWordsAttrSet;
    //普通文本属性接口
    private MutableAttributeSet normalWordsAttrSet;
    private MutableAttributeSet inputAttributes = new RTFEditorKit().getInputAttributes();
    //定义关键字数组
    private String[] keyWordArrary = {
            "select","insert","delete","update","create","drop","alter","table","view","index","procedure","function","trigger",
            "column","values","set","as","is",
            "from","where","and","or","not","in","between","join","left","right","into","exists",
            "limit","on",
            "inner","null","primary","key","check","default",
            "distinct","all","union",
            "group","by","order","desc","asc","having",
            "min","max","count","sum","avg","case","when","then","else",
            "begin","end","loop",
            "varchar","char","text","int", "float"};

    public SQLEdit() {
        keyWordsAttrSet = new SimpleAttributeSet();
        normalWordsAttrSet = new SimpleAttributeSet();

        styleContext = new StyleContext();
        defaultStyledDocument = new DefaultStyledDocument(styleContext);

        StyleConstants.setForeground(keyWordsAttrSet, Color.blue);
        StyleConstants.setForeground(normalWordsAttrSet, Color.black);

        this.setDocument(defaultStyledDocument);

        //为编辑器添加键盘释放事件
        this.addKeyListener(new KeyAdapter() {
            //前一次光标位置
            int preCaretPosition;
            //当前光标位置
            int currentCaretPosition;
            //判断是否是粘贴操作
            boolean isPaste=false;

            //键 按下
            @Override
            public void keyPressed(KeyEvent e) {
                //重置标量
                isPaste=false;
                //prePosition
                preCaretPosition = getCaretPositionForEdit();
                //ctrol + v ,command + v
                if((e.isMetaDown()||e.isControlDown()) && e.getKeyChar() == 'v'){
                    isPaste=true;
                }
            }
            //键 释放
            @Override
            public void keyReleased(KeyEvent e) {
                //currposition
                currentCaretPosition = getCaretPositionForEdit();
                if(isPaste){
                    //粘贴文本
                    for(int i=preCaretPosition;i<=currentCaretPosition;i++){
                        sqlSyntaxParse(i);
                    }

                }else{
                    //正常输入文本
                    sqlSyntaxParse(currentCaretPosition);
                }
            }
        });

    }

    public int getCaretPositionForEdit(){
        return this.getCaretPosition();
    }
    /**
     * SQL 语法分析方法
     */
    public void sqlSyntaxParse(int cursorPostion) {
        try {
            String sqlText = null;
            //获取默认的根元素
            Element root = defaultStyledDocument.getDefaultRootElement();
            //文本组件的文本插入位置
//            int cursorPostion = this.getCaretPosition();
            //当前行索引
            int lineIndex = root.getElementIndex(cursorPostion);
            Element rowElement = root.getElement(lineIndex);
            //当前行文本偏移量 开始位置
            int start = rowElement.getStartOffset();
            //当前行文本偏移量 结束位置
            int end = rowElement.getEndOffset() - 1;
            //得到文本
            sqlText = defaultStyledDocument.getText(start, end - start);

            //关键字数组下标
            int keyWordArrayIndex = 0;
            int startPostion = 0;
            defaultStyledDocument.setCharacterAttributes(start, sqlText.length(), normalWordsAttrSet, false);
            SQLTokenizer st = new SQLTokenizer(sqlText);
            while (st.hasMoreTokens()) {
                sqlText = st.nextToken();
                if (sqlText == null) return;
                for (keyWordArrayIndex = 0; keyWordArrayIndex < keyWordArrary.length; keyWordArrayIndex++) {
                    if (sqlText.equalsIgnoreCase(keyWordArrary[keyWordArrayIndex])) {
                        break;
                    }
                }
                if (keyWordArrayIndex >= keyWordArrary.length){
                    continue;
                }
                startPostion = st.getCurrPosition();

                //将关键字添加样式
                defaultStyledDocument.setCharacterAttributes(start + startPostion, sqlText.length(), keyWordsAttrSet, false);
            }
            inputAttributes.addAttributes(normalWordsAttrSet);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
